home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d2 / stayres.arc / STAYSAVE.340 < prev    next >
Text File  |  1988-06-27  |  9KB  |  147 lines

  1. {****************************************************************************}
  2. {                 S  T  A  Y  S  A  V  E  .  I  N  C                         }
  3. {****************************************************************************}
  4.  
  5. {This Inline routine will save the regs and Stack for Stay resident programs.
  6.  It restores DS and SS from the previously saved integer constants "OurDseg"
  7.  and "OurSSeg". This is important since Dos is not re-entrant and any attempt
  8.  to use Interrupt I/O services will clobber the very stack on which the
  9.  Resident Turbo program just saved its regs. Thus, on the final return, you
  10.  and Toto will end up somewhere other than Kansas and without your Ruby Reds.
  11.    }
  12. { author: Copyright (C)  Lane Ferris
  13.               - The Hunter's Helper -
  14.  
  15.        Distributed to the Public Domain for use without profit.
  16.                     Original Version 5.15.85
  17. }
  18.            { On entry the Stack will already contain: }
  19.            {  1) Sp for Dos                           }
  20.            {  2) Bp for Dos                           }
  21.            {  3) Ip for Dos                           }
  22.            {  4) Cs for Dos                           }
  23.            {  5) Flags for Dos                        }
  24.   Inline (
  25.  
  26.  { The following routine avoids the overhead of saving the DOS stack         }
  27.  { when the INT 16 function was not for a character request. This happens    }
  28.  { often (every four chars) as DOS checks on ^S/^Q/^C/Keypressed  ad.nausea  }
  29.  
  30.    $9C/                                {PushF         Save Flags             }
  31.    $80/$FC/$00/                        {Cmp Ah,00     If Char request,       }
  32.    $75/$17/                            {Jne  Skipit   Not for us.            }
  33.    $2E/
  34.    $FF/$1E/Dos_Intip/                  {Call Far Cs:[Original$16]            }
  35.    $9C/                                {PushF          Save Return Flags     }
  36.    $80/$FC/Our_Char/                   {Cmp   Ah,Cs:OurChar  Our Key?        }
  37.    $74/$1A/                            {Je GotIt       enter Staysave code   }
  38.                                        {POPF           Restore Int 16 flags  }
  39.     $EB/$01/                           {JMP $+3 Skip over IRET   }
  40.     $CF/                               {IRET    POP IP/CS/Flags  }
  41.     $0E/                               {PUSH CS Make a return    }
  42.     $E8/$FB/$FF/                       {CALL CS:$-2 Pop the Flags}
  43.  
  44.    $5D/$5D/                            {Pop BP/PopBP   Restore BP            }
  45.    $CA/$02/$00/                        {RetF 2   Return w/Key discard flags  }
  46.  
  47. {Skipit}                               {Jmp to Original Dos Intr $16         }
  48.                                        {PopF  Restore the Flags              }
  49.     $EB/$01/                           {JMP $+3 Skip over IRET   }
  50.     $CF/                               {IRET    POP IP/CS/Flags  }
  51.     $0E/                               {PUSH CS Make a return    }
  52.     $E8/$FB/$FF/                       {CALL CS:$-2 Pop the Flags}
  53.  
  54.    $5D/$5D/                            {Pop  Bp/Pop Bp else  Restore Bp &    }
  55.    $2E/                                {     Jump to Original Dos Interrupt  }
  56.    $FF/$2E/Dos_IntIP/                  {Jmp Far Cs:[DOS_IntIp]               }
  57.  
  58.             { Move the current active registers to a safe place}
  59. {GotIt}
  60.                                        {Pop Saved Flags}
  61.     $EB/$01/                           {JMP $+3 Skip over IRET   }
  62.     $CF/                               {IRET    POP IP/CS/Flags  }
  63.     $0E/                               {PUSH CS Make a return    }
  64.     $E8/$FB/$FF/                       {CALL CS:$-2 Pop the Flags}
  65.     $FA /                              {Cli         Stop all interrupts       }
  66.                                        { Bp and Sp aready saved at Begin Stmt }
  67.     $55/                               {Push   Bp  Save again for Regpak      }
  68.     $BD/Regs/                          {Mov    Bp,offset REGS address savearea}
  69.     $2E/$89/$46/$00/                   {CS:Mov [Bp+0],AX Save Users Registers }
  70.     $2E/$89/$5E/$02/                   {Cs:Mov [Bp+2],Bx}
  71.     $2E/$89/$4E/$04/                   {CS:Mov [Bp+4],CX}
  72.     $2E/$89/$56/$06/                   {CS:Mov [Bp+6],DX}
  73.     $2E/$8F/$46/$08/                   {Pop    Cs:[Bp+8] Fetch Bp from stack  }
  74.     $2E/$89/$76/$0A/                   {CS:Mov [Bp+A],SI}
  75.     $2E/$89/$7E/$0C/                   {CS:Mov [Bp+C],DI}
  76.     $2E/$8C/$5E/$0E/                   {CS:Mov [Bp+E],DS}
  77.     $2E/$8C/$46/$10/                   {CS:Mov [Bp+10],ES}
  78.     $9C/                               {PUSHF  put Flags on stack to retrieve }
  79.     $2E/$8F/$46/$12/                   {POP Cs:[Bp+12]}
  80.  
  81.                { If Current SS := [OurSseg] or (Inuse = True), }
  82.                { then dont overlay the previously saved stack. }
  83.                { This program is being recursive.              }
  84.  
  85.      $2E/$80/$3E/Inuse/$01/   {Cmp  Cs:[Inuse],1   Inuse = True ?         }
  86.      $74/$62/                 {Je   ReCurin        Yes, -J-U-M-P-         }
  87.  
  88.                { Switch the SS:Sp reg pair over to ES:Si       }
  89.                { Put Turbo's Stack pointers into SS:Sp         }
  90.  
  91.      $2E/$8C/$16/DosSSeg/     {Mov  Cs:DosSSeg,SS Save Dos Stack Segment    }
  92.      $8C/$D6/                 {Mov  Si,SS         Es gets Dos stack         }
  93.      $8E/$C6/                 {Mov  Es,Si                                   }
  94.      $2E/$8E/$16/OurSSeg/     {Mov  SS,Cs:OurSSeg SS Gets our Stack segment }
  95.      $2E/$8E/$1E/OurDseg/     {Mov  Ds,Cs:Our_Ds  DS Gets our Data Segment  }
  96.  
  97.                { If ES:Si (stack ptr) <>  OurSSeg  then        }
  98.                { Sp := Virgin Turbo Stack pointer.             }
  99.                { If Es:Si := OurSSeg, then this is a Read or   }
  100.                { Write before Inuse was set True. Dont clobber }
  101.                { the current setting of Turbo stack pointer.   }
  102.  
  103.      $2E/$3B/$36/OurSSeg/     {Cmp  Si,Cs:OurSSeg If SS := OurSSeg then     }
  104.      $89/$E6/                 {Mov  Si,Sp         dont clobber saved regs   }
  105.      $74/$05/                 {Je   $+5           else get virgin stack ptr }
  106.      $3E/$8B/$36/$74/$01/     {Mov  Si,Ds:[174]   ..(cf. code at B2B 3.0x)  }
  107.      $87/$F4/                 {Xchg Sp,Si         Set new  Stack Pointer    }
  108.  
  109.                { Stack Dos/User interrupted pgm regs for Exit. }
  110.                { These are the original interrupt process regs }
  111.                { that must be returned on interrupt return     }
  112.  
  113.      $2E/$FF/$76/$00/         {Push [Bp+0]  Save Ax                         }
  114.      $2E/$FF/$76/$02/         {Push [Bp+2]  Save Bx                         }
  115.      $2E/$FF/$76/$04/         {Push [Bp+4]  Save Cx                         }
  116.      $2E/$FF/$76/$06/         {Push [Bp+6]  Save Dx                         }
  117.                               {Push [Bp+8]  Save Bp                         }
  118.      $2E/$FF/$76/$0A/         {Push [Bp+A]  Save Si                         }
  119.      $2E/$FF/$76/$0C/         {Push [Bp+C]  Save Di                         }
  120.      $2E/$FF/$76/$0E/         {Push [Bp+E]  Save Ds                         }
  121.      $2E/$FF/$76/$10/         {Push [Bp+10] Save Es                         }
  122.  
  123.                { Now stack the lesser of current stack size or  }
  124.                { 40 Words to our stack, to be returned on the   }
  125.                { interrupted pgms stack on exit. This is done   }
  126.                { to allow recursive entry into Dos/or other non }
  127.                { re-entrant pgms.                               }
  128.  
  129.      $29/$C9/                 {Sub  Cx,Cx  Find minimum of current stack    }
  130.      $29/$F1/                 {Sub  Cx,Si  size or 40 words to save.        }
  131.      $D1/$E9/                 {Shr  Cx,1   Stackbytes/2 for words.          }
  132.      $83/$F9/$40/             {Cmp  Cx,+40 This keeps us from overrunning   }
  133.      $7E/$03/                 {Jle  $+3    the Stack Segment when it is less}
  134.      $B9/$40/$00/             {Mov  Cx,40  than Dos stack size              }
  135.      $2E/$89/$0E/StackSize/   {Mov  Cs:StackSize,Cx Save current stack size }
  136.  {Restack:}
  137.      $26/$FF/$34/             {Push Es:[Si] Our Stack := Dos Es:Si          }
  138.      $46/$46/                 {Inc  Si/Inc Si Get Next Dos Stack Word       }
  139.      $E2/$F9/                 {Loop to Restack                              }
  140.  
  141.      $56/                     {Push Si            Save bottom of Dos Stack  }
  142.      $2E/$8C/$5E/$0E/         {Mov  Cs:[Bp+E],Ds  Set New Data Segmt in regs}
  143. {Recurin}                     {                     Jump here if Recursion  }
  144.      $FB                      {Sti Enable Interrupts                        }
  145.  
  146.        ) ;
  147. {...........................................................................}